#include "main.h"
// 初始化名为s的栈，初始化成功，返回0，否则返回1。
int init_stack(Stack *s){
    (*s)= malloc(sizeof(struct stack));
    int  *p=(int*) malloc(STACK_MAX_SIZE*sizeof (int));
    (*s)->base=p;
    if(!(*s)->base) return 1;
    (*s)->top=(*s)->base;
    (*s)->number_of_elements=STACK_MAX_SIZE;
    return 0;
}
// 入栈。返回值表示是否压栈成功：0，成功；1，不成功。
int push(Stack s, char operator_or_operand){
    if(s->top-s->base==s->number_of_elements){
        return 1;
    } else{
//        *s->top++=operator_or_operand;
        *(s->top) = operator_or_operand;
        s->top++;
        return 0;
    }

}
// 出栈。返回值表示是否出栈成功：0，成功，1，不成功。
int pop(Stack s, char * p_operator_or_operand){
    if(s->top==s->base) return 1;
    s->top--;
    *p_operator_or_operand= *(s->top);
    return 0;
}
// 只返回栈顶元素，通过result变量返回栈顶元素的值。函数返回值用于表示执行状态：0，成功；1，不成功。
int get_top(Stack s, char * symbol){
    if(s->top!=s->base){
        *symbol =*(s->top-1);
        return 0;
    }
    else return 1;
}
// 判断刚扫描到的symbol是否操作符。如果symbol是操作符，返回1，否则返回0。
bool is_operator(char symbol){
    char operator[7] = {'+','-','*','/','(',')','#'};/*创建一个标识符数组*/
    for (int i = 0; i < 7; ++i) {
        if(operator[i] == symbol){/*判读扫描到的symbol是否为操作数*/
            return 1;
        }
    }
    return 0;
}
// 判断刚扫描到的symbol是否操作数。如果symbol是操作数，返回1，否则返回0。
bool is_operand(char symbol){
    char operator[10] = {'0','1','2','3','4','5','6','7','8','9'};/*建立一个操作数数组*/
    for (int i = 0; i < 10; ++i) {
        if(operator[i] == symbol){/*判读扫描到的symbol是否为操作数*/
            return 1;
        }
    }
    return 0;
}
// 处理操作符。operator_on_stack_top表示操作符栈栈顶的操作符，just_scanned_operator表示从表达式里刚刚读取的操作符。返回值表示优先级：
//  -1, operator_on_stack_top 的优先级低于 just_scanned_operator；
//  0，operator_on_stack_top 的优先级等于 just_scanned_operator；
//  1，operator_on_stack_top 的优先级高于 just_scanned_operator。
char youxianji_bijiao(char operator_on_stack_top,char just_scanned_operator){
    int i, j;
    char youxianji[][7] = {
            /*运算符之间的优先级制作成一张表格*/
            {'>', '>', '<', '<', '<', '>', '>'},
            {'>', '>', '<', '<', '<', '>', '>'},
            {'>', '>', '>', '>', '<', '>', '>'},
            {'>', '>', '>', '>', '<', '>', '>'},
            {'<', '<', '<', '<', '<', '=', '0'},
            {'>', '>', '>', '>', '0', '>', '>'},
            {'<', '<', '<', '<', '<', '0', '='}
    };
    switch(operator_on_stack_top){
        case '+': i=0; break;
        case '-': i=1; break;
        case '*': i=2; break;
        case '/': i=3; break;
        case '(': i=4; break;
        case ')': i=5; break;
        case '#': i=6; break;
    }
    switch (just_scanned_operator) {
        case '+':j = 0;break;
        case '-':j = 1;break;
        case '*':j = 2;break;
        case '/':j = 3;break;
        case '(':j = 4;break;
        case ')':j = 5;break;
        case '#':j = 6;break;
    }
    switch (youxianji[i][j]) {
        case '>':
            return 1;
        case '<':
            return -1;
        case '=':
            return 0;
    }
}
// 用于简单计算+，-，*，/，operator表示操作符，left_operand表示左操作数，right_operand表示右操作数，结果通过result返回。函数返回值表示计算状态：0，计算成功；1，不成功。
int jisuan(char operator,char left_operand,int right_operand, int* result){
    int i , j;
    switch (left_operand) {
        case'0': i = 0;break;
        case'1': i = 1;break;
        case'2': i = 2;break;
        case'3': i = 3;break;
        case'4': i = 4;break;
        case'5': i = 5;break;
        case'6': i = 6;break;
        case'7': i = 7;break;
        case'8': i = 8;break;
        case'9': i = 9;break;
    }
    switch (right_operand) {
        case'0': j = 0;break;
        case'1': j = 1;break;
        case'2': j = 2;break;
        case'3': j = 3;break;
        case'4': j = 4;break;
        case'5': j = 5;break;
        case'6': j = 6;break;
        case'7': j = 7;break;
        case'8': j = 8;break;
        case'9': j = 9;break;
    }

    switch (operator) {
        case '+':*result = i + j;break;
        case '-':*result = i - j;break;
        case '*':*result = i * j;break;
        case '/':
            if (j!=0) {
                *result = i / j;
            }
            else{
                printf("除数不能为零！\n");
                exit(0);
            }
            break;
    }
    return 0;
}

int evaluate(char * expression, int * result){
    Stack OPTR;
    Stack OPND;
    char left_operand;
    char right_operand;
    init_stack(&OPTR);
    init_stack(&OPND);

    int char_position = 0;
    push(OPTR, expression[char_position]);
    char_position +=1;
    char top;
    char w = expression[char_position];

    while(w != '#' || top != '#')
    {
        if(is_operand(w))
        {
            push(OPND, w);
            char_position += 1;
            w = expression[char_position];
        }
        if(is_operator(w))
        {   char c;
            get_top(OPTR, &c);
            char Total;
            int RESULT;
            switch (youxianji_bijiao(c,w)) {
                case -1:
                    push(OPTR, w);
                    w = expression[++char_position];
                    break;
                case 0:
                    pop(OPTR, &c);
                    w = expression[++char_position];
                    break;
                case 1:
                    pop(OPND, &right_operand);
                    pop(OPND, &left_operand);
                    pop(OPTR, &c);
                    if (c == '#' || left_operand == 0){
                        *result = 1;
                        return *result;
                    }else {
                        jisuan(c, left_operand, right_operand, &RESULT);
                        Total = RESULT + 48;
                        push(OPND, Total);
                    }
                    break;
            }
        }
        get_top(OPTR, &top);
    }
    get_top(OPND, &top);
    *result = top - 48;
    return *result;
}
int main(int argc, char * argv[]) {
    int result;
    int is_exp_valid = evaluate("#1+2#", &result);
    printf("result:%d", is_exp_valid);
}